<template>
  <base-modal :show.sync="visible" width="650px" class="base-export-modal">
    <template slot="title">
      <h3 v-if="isShowExportTip">
        {{$t('component.baseExport.title')}}
        <el-tooltip placement="top">
          <template slot="content">
            {{$t('component.baseExport.tooltip')}}
            <span class="export-link" @click="toExport">{{$t('component.baseExport.toImport')}}</span>
          </template>
          <i class="iconfont icon-warning-circle-fill task-icon icon-color"></i>
        </el-tooltip>
      </h3>
      <h3 v-else>
        {{$t('component.baseExport.title')}}
      </h3>
    </template>
    <div>
      <el-checkbox v-model="isCheckedAll" @change="toggle">{{$t('common.base.selectAll')}}</el-checkbox>
    </div>
    <el-checkbox-group
      v-model="checkedArr"
      @change="handleChange"
      style="width:100%;"
      class="base-export-field-wrap"
    >
      <template v-for="(col, index) in filterColumns">
        <el-checkbox
          v-if="!col.conType || col.conType !== 'btnArray'"
          :key="`${col.field}_${index}`"
          :label="col.exportAlias ? col.exportAlias : col.field"
          :disabled="col.disabled ? col.disabled : false"
        >
          {{col.label}}
        </el-checkbox>
      </template>
    </el-checkbox-group>

    <div slot="footer" class="export-footer">
      <div class="export-footer-left">
        <template v-if="isShowCustomTips">
          <i class="iconfont icon-charts"></i>
          <span>{{ $t('frame.backgroundTask.text23') }}</span>
          <a @click="toCustomChart" class="btn-link" href="javascript:;">{{ $t('frame.backgroundTask.text24') }}</a>
        </template>
      </div>
      <div>
        <button type="button" class="btn base-modal-text-btn" @click="visible = false">{{$t('common.base.close')}}</button>
        <button
          type="button"
          class="btn btn-primary"
          :disabled="pending"
          @click="exportData"
        >
          {{pending ? $t('common.base.exporting') : $t('common.base.export')}}
        </button>
      </div>
    </div>

    <div class="base-export-bridge" ref="bridge"></div>
  </base-modal>
</template>

<script>
import { t } from '@src/locales'
import Platform from "@src/platform";
import http from "@src/util/http";
import objHttp from '@src/util/HttpUtil';   // 不以form表单提交
import _ from 'lodash'
import qs from '@src/util/querystring'
const MAX_COUNT = 999999999;
import { openAccurateTab } from '@src/util/platform';
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum'
import StorageModuleEnum from '@model/enum/StorageModuleEnum'
import { storageGet, storageSet } from '@src/util/storage.ts'
import { showExportListAlert } from '@src/util/alert';
import { getRootWindowInitData } from '@src/util/window'
const rootWindowInitData = getRootWindowInitData();

export default {
  name: 'base-export',
  props: {
    columns: Array,
    action: String,
    buildParams: Function,
    title: {
      type: String,
      default: t('component.baseExport.title'),
    },
    method: {
      type: String,
      default: 'get'
    },
    needObjReq:{
      type:Boolean,
      default:false
    },
    /**
     * 函数必须返回Promise对象
     * 如果验证失败，promise需要返回错误信息，否则返回null
     */
    validate: Function,
    downloadUrl: String,
    isDownloadFormMode: {
      type: Boolean,
      default: false
    },
    /**
     * @des 针对部分需要分页参数的导出
     */
    listPage: {
      type: Object,
      default: ()=>({})
    },
    isShowExportTip:{
      type: Boolean | String,
      default: false,
    },
    storageKey: {
      type: String,
      default: '',
    },
    isUserListFlag:{
      type:Boolean,
      default:false
    },
  },
  data() {
    return {
      ids: [],
      fileName: '',
      visible: false,
      pending: false,
      checkedArr: [],
      isCheckedAll: true,
      isDownloadNow: false, // 导出是否是立刻下载模式
      checked: ''
    };
  },
  computed: {
    filterColumns() {
      return this.columns.filter(item => item.export);
    },
    authorities() {
      return rootWindowInitData?.user?.auth || {};
    },
    isShowCustomTips() {
      return this.authorities?.REPORT_CREATE == 3;
    },
  },
  methods: {
    // 跳转自定义报表
    toCustomChart() {
      openAccurateTab({
        type: PageRoutesTypeEnum.PageCustomCharts,
        params: `chartType=table&dataset=task`,
        reload: true,
      })
    },
    toExport(){
      openAccurateTab({
        type: PageRoutesTypeEnum.PageSecurityDepartment,
      })
    },
    buildParamsFunc() {
      return typeof this.buildParams == 'function'
        ? this.buildParams(this.checkedArr, this.ids)
        : { checked: this.checkedArr.join(','), ids: this.ids.join(',') };
    },
    isCheckedEmpty() {
      return this.checkedArr.length == 0;
    },
    async open(ids = [], fileName = `${t('common.base.exportData')}.xlsx`, isDownloadNow = false) {
      const { checkedArr, isCheckedAll } = await this.getExportStorageData(this.storageKey);
      
      this.pending = false;
      this.ids = ids;
      this.fileName = fileName;

      this.checkedArr = checkedArr || this.filterColumns.map(item =>
        item.exportAlias ? item.exportAlias : item.field
      );
      this.isCheckedAll = isCheckedAll;
      this.isDownloadNow = isDownloadNow;

      this.visible = true;
    },
    toggle(value) {
      if (!value) {
        this.checkedArr = this.filterColumns.filter(item => item.disabled).map(item => item.exportAlias ? item.exportAlias : item.field)
        return
      }
      
      this.checkedArr = this.filterColumns.map(item => item.exportAlias ? item.exportAlias : item.field)
    },
    handleChange() {
      this.isCheckedAll = this.checkedArr.length == this.filterColumns.length;
    },
    // 表单形式导出 TODO: 修改
    formExport(params) {
      let form = document.createElement('form');
      this.$refs.bridge.appendChild(form);

      for (let prop in params) {
        let input = document.createElement('input');
        input.name = prop;
        input.value = params[prop];
        form.appendChild(input);
      }

      form.method = this.method;
      form.action = this.action;
      form.submit();

      this.visible = false;
      this.pending = false;

      setTimeout(() => {
        this.$refs.bridge.removeChild(form);
      }, 150);
    },
    // ajax形式导出
    async ajaxExport(params) {
      let ajax = null;
      // 是否是立即下载
      if (this.isDownloadNow) {
        if (this.downloadUrl) {
          this.billExport(params);
          return;
        }
        let config = { responseType: 'blob' }
        if (this.isDownloadFormMode) {
          config.headers = {
            arrayFormat: 'repeat'
          }
        }
        ajax = http
          .axios(this.method, this.action, params, false, config)
          .then(blob => {
            let link = document.createElement('a');
            let url = URL.createObjectURL(blob);
            link.download = this.fileName;
            link.href = url;
            this.$refs.bridge.appendChild(link);
            link.click();

            this.visible = false;
            this.pending = false;
            setTimeout(() => {
              URL.revokeObjectURL(url);
              this.$refs.bridge.removeChild(link);
            }, 150);
          })
          .catch(err => console.error(err));
      } else {
        if(this.needObjReq){
          let total_ = this.listPage?.total || 0
          let model = {
            checked: this.checkedArr.join(','),
            ids: this.ids.join(','),
            ...(total_ ? {total:total_} : {})
          };
          _.assign(model, params);

          let ua = navigator.userAgent;
          if (ua.indexOf('Trident') >= 0) {
            window.location.href = `${this.action}?${qs.stringify(model)}`;
            this.visible = false;
            return;
          }

          ajax = objHttp
            .post(this.action, model, true)
            .then(res => {
              this.visible = false;
              this.pending = false;

              // Platform.alert(res.message);

              if (res.status == 0) {
                showExportListAlert(res.message)
              }else{
                Platform.alert(res.message);
              }
            })
            .catch(err => console.error(err));
        }else{
          ajax = http
            .axios(this.method, this.action, params, false)
            .then(res => {
              this.visible = false;
              this.pending = false;

              if (res.status == 0) {
                showExportListAlert(res.message)
              }else{
                Platform.alert(res.message);
              }
            })
            .catch(err => console.error(err));  
        }
      }

      return ajax;
    },
    async billExport(params) {
      try {
        let ajax = null;
        let token = await http.post(this.downloadUrl, params);
        let url = `${ this.action }?token=${ token.data || token.message }`;
        ajax = http.axios(this.method, url, {}, false, {responseType: 'blob'}).then(blob => {
          let link = document.createElement('a');
          let url = URL.createObjectURL(blob);
          link.download = this.fileName;
          link.href = url;
          this.$refs.bridge.appendChild(link)
          link.click();

          this.visible = false;
          this.pending = false;
          setTimeout(() => {
            URL.revokeObjectURL(url);
            this.$refs.bridge.removeChild(link)
          }, 150);
        }).catch(err => console.error(err));

        return ajax;
      } catch (error) {
        console.error(error)
      }
    },

    async exportData() {
      if (this.checkedArr.length == 0) return Platform.alert(t('common.base.exportModal.atLeastOne'))
      this.pending = true;
      if(this.isUserListFlag) {
        this.$emit('goExport',this.checkedArr) 
        this.pending = false;
        this.visible = false;
        return
      }

      try {
        // 如果提供验证函数，则进行验证
        if(typeof this.validate == 'function'){
          let validateRes = await this.validate(this.ids, MAX_COUNT)
          if(validateRes) {
            this.pending = false;
            this.visible = false;
            return Platform.alert(validateRes)
          }
        }

        let params = (
          typeof this.buildParams == 'function'
            ? this.buildParams(this.checkedArr, this.ids)
            : {checked: this.checkedArr.join(','), ids: this.ids.join(',')}
        )
        
        this.setExportStorageData(
          this.storageKey, 
          {
            checkedArr: this.checkedArr,
            isCheckedAll: this.isCheckedAll,
          }
        )

        return navigator.userAgent.indexOf('Trident') >= 0 ? this.formExport(params) : this.ajaxExport(params)

      } catch (error) {
        console.error(error)
      }
    },

    async setExportStorageData(key, data) {
      if(!key || key === 'empty') return
      storageSet(key, data, StorageModuleEnum.Export)
    },

    async getExportStorageData(key) {
      const defaultObj = { checkedArr: null, isCheckedAll: true };
      return await storageGet(key, defaultObj, StorageModuleEnum.Export)
    }
  }
};
</script>

<style lang="scss">
  @import './BaseExport.scss';
</style>
<style lang="scss" scoped>
.export-link {
  color: $color-primary-light-6;
  cursor: pointer;
  text-decoration: underline;
}

.export-footer-left {
    font-size: 13px;
    color: #595959;
    display: flex;
    align-items: center;

    span {
      padding-left: 3px;
    }
    a {
      @include fontColor();
    }
  }

</style>